package com.itheima.pinda.authority.biz.service.auth.impl;

import com.itheima.pinda.authority.biz.service.auth.ValidateCodeService;
import com.itheima.pinda.common.constant.CacheKey;
import com.itheima.pinda.exception.BizException;
import com.wf.captcha.ArithmeticCaptcha;
import com.wf.captcha.base.Captcha;
import lombok.extern.slf4j.Slf4j;
import net.oschina.j2cache.CacheChannel;
import net.oschina.j2cache.CacheObject;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @Description: 验证码
 * @Author: ysf
 * @CreateTime: 2024-11-13  11:13
 * @Version: 1.0
 */

@Slf4j
@Service
public class ValidateCodeServiceImpl  implements ValidateCodeService {

    @Autowired
    private CacheChannel cacheChannel;

    /**
    *  生成验证码并进行缓存
    * @param key
	* @param response
    * @return void
    */
    @Override
    public void create(String key, HttpServletResponse response) throws IOException {
        //1、校验是否为空
        if(StringUtils.isBlank(key)){
            throw BizException.validFail("验证码key不能为空");
        }
//        response.setContentType(MediaType.IMAGE_PNG_VALUE);
//        这行代码设置了HTTP响应的内容类型（Content-Type）为PNG图片。MediaType.IMAGE_PNG_VALUE是一个常量，通常等价于字符串"image/png"。这意味着告诉客户端，服务器返回的数据是一张PNG格式的图片。
//        response.setHeader(HttpHeaders.PRAGMA,"No-cache");
//        这行代码通过Pragma头部来尝试防止页面被缓存。Pragma: No-cache是一个HTTP/1.0的遗留字段，用来告诉浏览器不要缓存这个页面的内容。虽然在现代浏览器中，这个头部的效果有限（因为HTTP/1.1引入了更复杂的缓存控制机制），但它仍然被一些旧的HTTP/1.0兼容的代理服务器所尊重。
//        response.setHeader(HttpHeaders.CACHE_CONTROL,"No-cache");
//        这行代码通过Cache-Control头部来更精确地控制缓存行为。Cache-Control: No-cache指示请求或响应消息不能从缓存中获取，即每次用户请求时，都需要向服务器发送请求，服务器会返回资源的最新版本，而不是从本地缓存中读取。
//        response.setDateHeader(HttpHeaders.EXPIRES,0L);
//        这行代码设置了Expires头部，用来指定资源过期的时间。0L表示一个特定的时间点，即Unix纪元时间（1970年1月1日00:00:00 GMT）。将Expires头部设置为这个时间点，实际上是告诉浏览器该资源已经过期，因此不应该被缓存。
        //2、响应验证码图片和信息
        response.setContentType(MediaType.IMAGE_PNG_VALUE);
        response.setContentType(MediaType.IMAGE_PNG_VALUE);
        response.setHeader(HttpHeaders.PRAGMA,"No-cache");
        response.setHeader(HttpHeaders.CACHE_CONTROL,"No-cache");
        response.setDateHeader(HttpHeaders.EXPIRES,0L);

        //3、生成验证码
        Captcha captcha = new ArithmeticCaptcha(115,42);
        captcha.setCharType(2);

        //4、缓存验证码
        cacheChannel.set(CacheKey.CAPTCHA,key,StringUtils.lowerCase(captcha.text()));

        //5、输出验证码图片
        captcha.out(response.getOutputStream());

    }

    /**
    * 校验验证码
    * @param key
	* @param value
    * @return boolean
    */
    @Override
    public boolean check(String key, String value) {
        //1、校验验证码
        if(StringUtils.isBlank(value)){
            throw BizException.validFail("请输入验证码");
        }

        //2、校验验证码是否存在
        CacheObject cacheObject = cacheChannel.get(CacheKey.CAPTCHA, key);
        if(cacheObject.getValue() == null){
            throw BizException.validFail("验证码已过期");
        }

        //3、校验验证码是否正确
        if(!value.equalsIgnoreCase(String.valueOf(cacheObject.getValue()))){
            throw BizException.validFail("验证码错误");
        }

        //4、验证通过，立即删除缓存中的验证码
        cacheChannel.evict(CacheKey.CAPTCHA,key);

        return true;
    }
}
